package com.beerandjesus.sportofkings.handicapper.dao;

import com.beerandjesus.sportofkings.handicapper.model.Sire;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Query;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * Date: 6/4/13
 * Time: 8:49 PM
 */
public abstract class SireHibernateDAO extends AbstractHibernateDAO {
    private BaseSireDataFactory factory = new BaseSireDataFactory();
    private String[] baseDataFiles;

    protected void buildDatabase(String tableName, Logger logger) throws DAOException {
        if (getBaseDataFiles() == null || getBaseDataFiles().length < 1) {
            throw new DAOException("No base data files provided");
        }
        dropAndCreate(DROP_TABLE + tableName, CREATE_TABLE + tableName +
                SireDAO.SIRE_TABLE_DEFINITION, logger);

        List<BaseSireData> data;
        try {
            data = factory.getBaseSireData(getBaseDataFiles());
        } catch (IOException e) {
            throw new DAOException("Error getting sire data", e);
        }
        for (BaseSireData d : data) {
            BigDecimal percentage = factory.getWinPercentage(d);
            getSession().save(newSire(d.getName(), percentage, d.getRating()));
        }
    }

    abstract protected Sire newSire(String name, BigDecimal percentage, BigDecimal rating);

    protected int getRowCount(String entityClass) {
        Query q = getSession().createQuery("select count(s) from " + entityClass + " s");
        Long count = (Long) q.uniqueResult();
        return (count == null ? 0 : count.intValue());
    }

    protected Sire getSireByName(String name, String entityClass) {
        if (StringUtils.isEmpty(name)) {
            return null;
        }
        Query q = getSession().createQuery("from " + entityClass + " where name = :name");
        q.setString("name", name.toUpperCase());
        return (Sire) q.uniqueResult();
    }

    public String[] getBaseDataFiles() {
        return baseDataFiles;
    }

    public void setBaseDataFiles(String[] baseDataFiles) {
        this.baseDataFiles = baseDataFiles;
    }
}
